package com.xunji.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunji.user.entity.Org;
import com.xunji.user.entity.Role;
import com.xunji.user.entity.User;
import com.xunji.user.entity.UserRole;
import com.xunji.user.mapper.UserMapper;
import com.xunji.user.service.RoleService;
import com.xunji.user.service.UserRoleService;
import com.xunji.user.service.UserService;
import com.xunji.user.util.Base64Util;
import com.xunji.user.util.PwdUtil;
import com.xunji.user.vo.rep.UserPageResponse;
import com.xunji.user.vo.req.UserAddRequest;
import com.xunji.user.vo.req.UserQueryRequest;
import com.xunji.user.vo.req.UserSearchRequest;
import com.xunji.user.vo.req.UserUpdateRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    RoleService roleService;
    @Autowired
    UserRoleService userRoleService;
    @Autowired
    OrgServiceImpl orgService;

    @Value("${user.default.pwd}")
    private String defaultPwd;

    @Override
    public User login(String userId) {
        QueryWrapper<User> qw = new QueryWrapper<User>().eq("id", userId).eq("status", 1);
        return this.getOne(qw);
    }

    @Override
    public User loginByName(String name) {
        QueryWrapper<User> qw = new QueryWrapper<User>().eq("login_name", name).eq("status", 1);
        return this.getOne(qw);
    }

    @Override
    public User getUserById(String id) {
        return this.getById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addUser(UserAddRequest request) {
        User user = User.getInstance(request);
/*        if (StringUtils.isEmpty(request.getImageName())) {
            user.setWithLoginImage(0);
        } else {
            user.setWithLoginImage(1);
        }*/
        user.setPassword(PwdUtil.encode(Base64Util.decode(defaultPwd)));
        this.save(user);
        if (!CollectionUtils.isEmpty(request.getRoleIds())) {
            userRoleService.batchSave(request.getRoleIds().stream().map(roleId -> UserRole.getInstance(user.getId(), roleId)).collect(Collectors.toList()));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUser(UserUpdateRequest request) {
        String id = request.getId();
        User user = this.getUserById(id);
        User.getInstance(request, user);
/*        if (StringUtils.isEmpty(request.getImageName())) {
            user.setWithLoginImage(0);
        } else {
            user.setWithLoginImage(1);
        }*/
        this.updateById(user);
        userRoleService.deleteByUserId(request.getId());
        if (!CollectionUtils.isEmpty(request.getRoleIds())) {
            userRoleService.batchSave(request.getRoleIds().stream().map(roleId -> UserRole.getInstance(request.getId(), roleId)).collect(Collectors.toList()));
        }
    }

    @Override
    public void deleteUser(String id) {
        User user = new User();
        user.setId(id);
        user.setStatus(2);
        this.updateById(user);
    }

    @Override
    public void restPwd(String id) {
        User user = new User();
        user.setId(id);
        user.setPassword(PwdUtil.encode(Base64Util.decode(defaultPwd)));
        this.updateById(user);
    }

    @Override
    public void updatePwd(String id, String pwd) {
        User user = new User();
        user.setId(id);
        user.setPassword(PwdUtil.encode(pwd));
        this.updateById(user);
    }

    @Override
    public List<User> getSimilarAccountByLoginName(String loginName) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight(!StringUtils.isEmpty(loginName), "login_name", loginName);
        return list(queryWrapper);
    }

    @Override
    public Page<UserPageResponse> page(UserQueryRequest request) {
        int orgId = request.getDepartmentId();
        Page<User> page = new Page<>(request.getPageNum(), request.getPageSize());
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("status", 1);
        // 查询当前节点的所有子节点
        ArrayList<Integer> orgIds = orgService.getAllChildrenId(orgId);
        qw.in("department_id", orgIds);
        qw.ne("login_name", "admin"); // 去除管理员
        qw.orderByDesc("created_time");
        if (!StringUtils.isEmpty(request.getName())) {
            qw.and(qr -> qr.like("name", request.getName())
                    .or()
                    .like("login_name", request.getName())
            );
        }
        //角色
        Page<User> users = this.baseMapper.selectPage(page, qw);
        Page<UserPageResponse> responsePage = new Page<>(request.getPageNum(), request.getPageSize());
        responsePage.setTotal(users.getTotal());
        List<Integer> departmentIds = users.getRecords().stream().map(User::getDepartmentId).collect(Collectors.toList());
        List<String> userIds = users.getRecords().stream().map(User::getId).collect(Collectors.toList());
        List<Org> orgs;
        Map<Integer, Org> orgMap = new HashMap<>();
        List<Role> roles;
        Map<String, Role> roleMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(departmentIds)) {
            orgs = orgService.getByIds(departmentIds);
            orgMap = orgs.stream().collect(Collectors.toMap(Org::getId, org -> org));
        }
        Map<String, List<String>> userRoleIdMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(userIds)) {
            List<UserRole> userRoles = userRoleService.selectByUserId(userIds);
            if (!CollectionUtils.isEmpty(userRoles)) {
                userRoleIdMap = userRoles.stream().collect(Collectors.groupingBy(UserRole::getUserId, Collectors.mapping(UserRole::getRoleId, Collectors.toList())));
                roles = roleService.listByIds(userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
                roleMap = roles.stream().collect(Collectors.toMap(Role::getId, role -> role));
            }
        }

        // 查询所有组织结构，封装用户上级部门
        HashMap<Integer, Org> orgMaps = new HashMap<>();
        List<Org> list = orgService.list();
        if (list != null && !list.isEmpty()) {
            list.forEach(org -> {
                orgMaps.put(org.getId(), org);
            });
        }
        List<UserPageResponse> userPageResponses = new ArrayList<>();
        if (!CollectionUtils.isEmpty(users.getRecords())) {
            for (User user : users.getRecords()) {
                UserPageResponse userPageResponse = new UserPageResponse();
                userPageResponse.setId(user.getId());
                userPageResponse.setName(user.getName());
                userPageResponse.setGender(user.getGender());
                Integer departmentId = user.getDepartmentId();
                userPageResponse.setDepartmentId(departmentId);
                userPageResponse.setPhoneNumber(user.getPhoneNumber());
                //userPageResponse.setWithLoginName(user.getWithLoginName());
                userPageResponse.setLoginName(user.getLoginName());
                //userPageResponse.setWithLoginImage(user.getWithLoginImage());
                if (orgMap.containsKey(departmentId)) {
                    userPageResponse.setDepartment(orgMap.get(departmentId).getName());
                }
                // 添加上级机构名称
                Integer userOrgId = user.getDepartmentId();
                if (orgMaps.get(userOrgId).getPId() == 0) {
                    userPageResponse.setPDepartment(orgMap.get(departmentId).getName());
                } else {
                    Integer pId = orgMaps.get(userOrgId).getPId();
                    userPageResponse.setPDepartment(orgMaps.get(pId).getName());
                }

                List<String> roleIds = userRoleIdMap.get(user.getId());
                List<Role> iRoles = new ArrayList<>();
                if (!CollectionUtils.isEmpty(roleIds)) {
                    for (String roleId : roleIds) {
                        iRoles.add(roleMap.get(roleId));
                    }
                }
                userPageResponse.setRoles(iRoles);
                userPageResponses.add(userPageResponse);
            }
            responsePage.setRecords(userPageResponses);
        }
        return responsePage;
    }

    @Override
    public List<User> selectByOrgId(Integer orgId) {
        QueryWrapper<User> qw = new QueryWrapper<User>().eq("department_id", orgId).eq("status", 1);
        return this.baseMapper.selectList(qw);
    }

    @Override
    public List<User> userSearchList(UserSearchRequest searchRequest, String userId) {
        // 根据关键字，查询name和loginName符合的数据
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.like(!StringUtils.isEmpty(searchRequest.getKeyword()), "name", searchRequest.getKeyword())
                .or()
                .like(!StringUtils.isEmpty(searchRequest.getKeyword()), "login_name", searchRequest.getKeyword());
        qw.eq("status", 1);
        qw.ne("id", userId); // 去除当前用户
        return this.baseMapper.selectList(qw);
    }

    public Long getUserCount(ArrayList<Integer> userIds) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("status", 1).in("department_id", userIds).ne("login_name", "admin"); // 去除管理员

        return this.baseMapper.selectCount(qw);
    }
}
